import os
import re
import sys
import json
import tempfile
import subprocess
from typing import List, Dict
from argparse import ArgumentParser

interceptor_dir = os.path.dirname(os.path.abspath(__file__))

def do_intercept(output_json_path: str, intercept_commands: str, origin_commands: List[str]) -> None:
    interceptor_clib_build_dir = os.path.join(interceptor_dir, 'clib/build/libinterceptor.so')
    build_script_path = os.path.join(interceptor_dir, 'scripts/build.sh')
    proc = subprocess.run(['bash', build_script_path], capture_output=False)
    if proc.returncode!= 0:
        print(f'Error building interceptor library: {proc.stderr.decode()}')
        sys.exit(1)
    else:
        print(f"build c lib succeeded")
    _, temp_log_path = tempfile.mkstemp()
    env = os.environ.copy()
    if 'LD_PRELOAD' in env:
        env['LD_PRELOAD'] = f'{interceptor_clib_build_dir} {env["LD_PRELOAD"]}'
    else:
        env['LD_PRELOAD'] = interceptor_clib_build_dir
    env['interceptor_log_path'] = temp_log_path
    if intercept_commands:
        env['interceptor_commands'] = intercept_commands
    proc = subprocess.run(origin_commands, env=env)
    if proc.returncode!= 0:
        print(f'Error running original commands: {proc.stderr.decode()}')
        os.remove(temp_log_path)
        sys.exit(1)
    with open(temp_log_path, 'r') as f:
        intercepted_commands = f.readlines()    
    os.remove(temp_log_path)
    command_db: List[Dict[str, str]] = []
    for command in intercepted_commands:
        if (obj := re.match(r'cd (.*) \&\& (.*)', command.strip())) is not None:
            work_dir = obj.group(1).strip()
            command = obj.group(2).strip()
            command_db.append({'work_dir': work_dir, 'command': command})

    if not command_db:
        print('No intercepted commands found')
        sys.exit(1)
    with open(output_json_path, 'w') as f:
        json.dump(command_db, f, indent=2)
    print(f'Intercepted commands saved to {os.path.abspath(output_json_path)}')
    
if __name__ == '__main__':
    parser = ArgumentParser(description='usage=%(prog)s [options]')
    parser.add_argument('-o', '--output', type=str, default='commands.json', help='output json file containing commands')
    parser.add_argument('-c', '--commands', type=str, required=False, help='commands to intercept')
    try:
        index = sys.argv.index('--')
        interceptor_argv = sys.argv[1:index]
        origin_command_argv = sys.argv[index + 1:]
        args = parser.parse_args(interceptor_argv)
        do_intercept(args.output, args.commands, origin_command_argv)
    except ValueError:
        parser.print_help()
        exit(1)